﻿/*********************************************************************
 * @file   FITKSimplifyMesh.h
 * @brief  简化网格，减少网格数量
 * @author zhangjingxuan (hiter25@outlook.com)
 * @date   2025-01-07
 *********************************************************************/
#ifndef __FITKSIMPLIFYMESH_H__
#define __FITKSIMPLIFYMESH_H__
#include "FITK2DMeshToolsAPI.h"
#include "FITKAbstractSimplifyMesh.h"
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
#include <OpenMesh/Tools/Decimater/DecimaterT.hh>

namespace Core
{
    class FITKNode;
    class FITKPoint;
}

namespace Interface
{
    class FITKElementTri3;
}

namespace Interface
{
    /**
     * @brief  简化网格类
     * @author zhangjingxuan (hiter25@outlook.com)
     * @date   2025-01-08
     */
    class FITK2DMeshToolsAPI FITKSimplifyMesh : public FITKAbstractSimplifyMesh
    {
    public:
        /**
         * @brief  OpenMesh网格精度设置double
         * @author zhangjingxuan (hiter25@outlook.com)
         * @date   2025-01-07
         */
        struct PolyTraits : public OpenMesh::DefaultTraits
        {
            typedef OpenMesh::Vec3d Point;
            typedef OpenMesh::Vec3d Normal;
        };
        typedef OpenMesh::TriMesh_ArrayKernelT<PolyTraits> FITKPlateMesh;
    public:
        FITKSimplifyMesh();
        ~FITKSimplifyMesh();
		/**
		 * @brief    获取简化后网格顶点,FITKSimplifyMeshPoint类型
		 * @return   QList<FITKSimplifyMeshPoint>
		 * @author   zhangjingxuan(hiter25@outlook.com)
		 * @date     2025-01-13
		 */
		QList<FITKSimplifyMeshPoint> getGeoPoint() override;
		/**
		 * @brief    获取简化后网格边界,FITKSimplifyMeshEdge类型
		 * @return   QList<FITKSimplifyMeshEdge>
		 * @author   zhangjingxuan(hiter25@outlook.com)
		 * @date     2025-01-13
		 */
		QList<FITKSimplifyMeshEdge> getGeoBoundary() override;
		/**
		 * @brief    获取简化后网格边,FITKSimplifyMeshEdge类型
		 * @return   QList<FITKSimplifyMeshEdge>
		 * @author   zhangjingxuan(hiter25@outlook.com)
		 * @date     2025-01-13
		 */
		QList<FITKSimplifyMeshEdge> getGeoEdge() override;
		/**
		 * @brief    获取简化后网格单元,FITKSimplifyMeshFace类型
		 * @return   QList<FITKSimplifyMeshFace>
		 * @author   zhangjingxuan(hiter25@outlook.com)
		 * @date     2025-01-13
		 */
		QList<FITKSimplifyMeshFace> getGeoFace() override;
        /**
         * @brief    获取简化后网格顶点
         * @return   QList<Core::FITKNode*> 网格顶点列表，FITKNode类型
         * @author   zhangjingxuan (hiter25@outlook.com)
         * @date     2025-01-07
         */
		QList<Core::FITKNode*> getMeshNode() override;
        /**
         * @brief    获取简化后网格单元
         * @return   QList<Interface::FITKElementTri3*> 网格顶点列表，FITKElementTri3类型
         * @author   zhangjingxuan (hiter25@outlook.com)
         * @date     2025-01-07
         */
		QList<Interface::FITKElementTri3*> getNodeElement() override;
        /**
         * @brief    网格简化
         * @param[i] n_vertices 剩余点数量
         * @param[i] n_faces 剩余面数量
         * @return   void
         * @author   zhangjingxuan (hiter25@outlook.com)
         * @date     2025-01-08
         */
        void simplifyMesh(size_t n_vertices = 0, size_t n_faces = 0) override;
        /**
         * @brief    三角形长宽比保护模块，设置三角形长宽比
         * @param[i] ratio 三角形长宽比
         * @return   void
         * @author   zhangjingxuan (hiter25@outlook.com)
         * @date     2025-01-07
         */
        void setTriAspectRatio(double ratio = 5.0) override;
        /**
         * @brief    锁定网格边界点
         * @return   void
         * @author   zhangjingxuan (hiter25@outlook.com)
         * @date     2025-01-07
         */
        void lockBoundary() override;
		/**
		 * @brief    锁定特征点，以相邻点组成两个向量的角度计算
		 * @param[i] angel1 最小角度
		 * @param[i] angel2 最大角度
		 * @return   void
		 * @author   zhangjingxuan(hiter25@outlook.com)
		 * @date     2025-01-14
		 */
		void lockVertices(double angel1, double angel2) override;
        /**
         * @brief    初始化板网格数据
         * @param[i] meshPoints 点数据
         * @param[i] meshFaces 面单元数据
         * @return   bool ture 初始化成功,false 初始化失败
         * @author   zhangjingxuan (hiter25@outlook.com)
         * @date     2025-01-07
         */
        bool initPlateMesh(const QList<Core::FITKNode*>& meshPoints, const QList<Interface::FITKElementTri3*>& meshFaces) override;
    private:
        /**
         * @brief  OpenMesh网格对象
         * @author zhangjingxuan (hiter25@outlook.com)
         * @date   2024-01-07
         */
        FITKPlateMesh* m_mesh{ nullptr };
        /**
         * @brief  OpenMesh网格简化对象
         * @author zhangjingxuan (hiter25@outlook.com)
         * @date   2025-01-07
         */
        OpenMesh::Decimater::DecimaterT<FITKPlateMesh>* m_decimater{ nullptr };
    };
}
#endif // !__FITKSIMPLIFYMESH_H__